package com.kld.common.cardcore;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

/**
 * Created by Administrator on 2015/9/22.
 */
public class SocketUtil {

    private Socket h;

    private BufferedReader is;
    private BufferedWriter os;

    public boolean ok = false;
    public String conerrmsg = null;

    /**
     * 连接加密机
     * @param ip
     * @param port
     * @return
     */
    public boolean connectHSM(String ip,int port){
        try{
            if(!ok){
                h = new Socket(ip,port);
                h.setSoLinger(true,0) ;
                is = new BufferedReader( new InputStreamReader(h.getInputStream() , "ISO-8859-1" ) );
                os = new BufferedWriter( new OutputStreamWriter(h.getOutputStream(), "ISO-8859-1" ) );
                ok = true;
            }
        } catch (Exception e){
            ok = false;
            System.out.println("error IN HSM_CMD_GenerateMAC Exception e:"+e.getMessage());
        }finally{
            if(!ok){
                allClose();
                return false;
            }else{
                return true;
            }
        }
    }

    /**
     * 加密机操作，发送+接收
     * @param len
     * @param instr
     * @return
     */
    public String HSMCmd(int len ,String instr){
        String outstr=null;
        String in=null;
        Integer h1,h2;
        byte[] head={0,0};
        h1 = new Integer(len/256);
        h2 = new Integer(len%256);
        head[0] =  h1.byteValue() ;
        head[1] =  h2.byteValue() ;
        try{
            in= new String(head,"ISO-8859-1") ;
            in+=instr.substring(0,len);
            SendToHSM(in);
            outstr = ReceFromHSM();
        }catch (Exception e ){
            System.out.println("IN HSMCmd error::: "+e.getMessage());
            return null;
        }
        return outstr;
    }

    /**
     * 发送数据到加密机
     * @param str
     */
    private void SendToHSM ( String str ){
        try
        {
            os.write(str);
            os.flush() ;
        }
        catch (Exception e )
        {
            String tempstr = null;
            ok = false;
            tempstr = "Possible Reason："+e.getMessage() ;
            System.out.println(tempstr);

        }

    }

    /**
     * 接受加密机返回数据
     * @return
     */
    private String ReceFromHSM(){
        String out= null;
        try
        {
            char [] out1=  new char[5000];
            int i = is.read(out1); //read(out1,0,1000) ;

            int j =out1[0]*256+out1[1];

            if(i!=j+2)
            {
                System.out.println("ERROR In ReceFromHSM read HSM return data! read len ="+i+"  HSMMSGLEN="+j);
                return null;
            }
            out = new String(out1).substring(2,i);
        }
        catch(Exception e)
        {
            System.out.println("in ReceFromHSM :"+e+out);
            return null;
        }
        return out;

    }

    public void allClose(){
        try
        {
            is.close() ;
            os.close() ;
            h. close() ;
            ok=false;
        }catch(Exception e){}
    }

    boolean Hex2Byte(byte[] in, byte[] out, int len)
    {
        byte[] asciiCode = {0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};

        if(len > in.length)
            return false;

        if(len % 2 != 0)
            return false;

        byte[] temp = new byte[len];

        for(int i=0; i<len; i++){
            if(in[i] >= 0x30 && in[i] <= 0x39)
                temp[i] = (byte)(in[i] - 0x30);
            else if(in[i] >= 0x41 && in[i] <= 0x46)
                temp[i] = asciiCode[in[i] - 0x41];
            else if(in[i] >= 0x61 && in[i] <= 0x66)
                temp[i] = asciiCode[in[i] - 0x61];
            else
                return false;

        }

        for(int i=0; i<len/2; i++)
        {
            out[i] = (byte)(temp[2*i]*16 + temp[2*i+1]);
        }

        return true;
    }

    boolean Byte2Hex(byte[] in, byte[] out, int len)
    {
        byte[] asciiCode = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46};

        if(len > in.length)
            return false;

        byte[] temp = new byte[2*len];

        for(int i=0; i<len; i++)
        {
            temp[2*i] = (byte)((in[i] & 0xf0)/16);
            temp[2*i+1] = (byte)(in[i] & 0x0f);
        }

        for(int i=0; i<2*len; i++)
        {

            if(temp[i] <= 9 && temp[i] >= 0)
            {
                out[i] = (byte)(temp[i] + 0x30);
            }
            else
            {
                out[i] = asciiCode[temp[i] - 0x0a];
            }
        }

        return true;
    }

}
